package com.cencat.user.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cencat.user.entity.User;
import com.cencat.user.dto.UserQueryDTO;
import com.cencat.user.vo.UserVO;
import com.cencat.user.vo.UserListVO;
import com.cencat.common.enums.UserStatus;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 用户数据访问层
 * @author cencat
 * @since 2024-01-01
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {

    /**
     * 根据用户名查询用户（支持多租户）
     * @param username 用户名
     * @param tenantId 租户ID
     * @return 用户信息
     */
    @Select("SELECT * FROM sys_user WHERE username = #{username} AND tenant_id = #{tenantId} AND deleted = 0")
    User selectByUsername(@Param("username") String username, @Param("tenantId") Long tenantId);

    /**
     * 根据邮箱查询用户（支持多租户）
     * @param email 邮箱
     * @param tenantId 租户ID
     * @return 用户信息
     */
    @Select("SELECT * FROM sys_user WHERE email = #{email} AND tenant_id = #{tenantId} AND deleted = 0")
    User selectByEmail(@Param("email") String email, @Param("tenantId") Long tenantId);

    /**
     * 根据手机号查询用户（支持多租户）
     * @param phone 手机号
     * @param tenantId 租户ID
     * @return 用户信息
     */
    @Select("SELECT * FROM sys_user WHERE phone = #{phone} AND tenant_id = #{tenantId} AND deleted = 0")
    User selectByPhone(@Param("phone") String phone, @Param("tenantId") Long tenantId);

    /**
     * 分页查询用户列表（支持多租户）
     * @param page 分页参数
     * @param queryDTO 查询条件
     * @return 用户列表
     */
    IPage<UserListVO> selectUserPage(IPage<UserListVO> page, @Param("query") UserQueryDTO queryDTO);

    /**
     * 根据ID查询用户详情（支持多租户）
     * @param userId 用户ID
     * @param tenantId 租户ID
     * @return 用户详情
     */
    @Select("SELECT * FROM sys_user WHERE id = #{userId} AND tenant_id = #{tenantId} AND deleted = 0")
    UserVO selectUserDetailById(@Param("userId") Long userId, @Param("tenantId") Long tenantId);

    /**
     * 统计用户数量（支持多租户）
     * @param queryDTO 查询条件
     * @return 用户数量
     */
    Long countUsers(@Param("query") UserQueryDTO queryDTO);

    /**
     * 批量更新用户状态（支持多租户）
     * @param userIds 用户ID列表
     * @param status 用户状态
     * @param tenantId 租户ID
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    int batchUpdateStatus(@Param("userIds") List<Long> userIds, 
                         @Param("status") UserStatus status, 
                         @Param("tenantId") Long tenantId,
                         @Param("updateBy") Long updateBy);

    /**
     * 更新最后登录信息
     * @param userId 用户ID
     * @param loginIp 登录IP
     * @param tenantId 租户ID
     * @return 更新数量
     */
    @Update("UPDATE sys_user SET last_login_time = NOW(), last_login_ip = #{loginIp}, login_count = login_count + 1, update_time = NOW() WHERE id = #{userId} AND tenant_id = #{tenantId}")
    int updateLastLoginInfo(@Param("userId") Long userId, 
                           @Param("loginIp") String loginIp, 
                           @Param("tenantId") Long tenantId);

    /**
     * 重置用户密码
     * @param userId 用户ID
     * @param newPassword 新密码
     * @param tenantId 租户ID
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    @Update("UPDATE sys_user SET password = #{newPassword}, update_time = NOW(), update_by = #{updateBy} WHERE id = #{userId} AND tenant_id = #{tenantId}")
    int resetPassword(@Param("userId") Long userId, 
                     @Param("newPassword") String newPassword, 
                     @Param("tenantId") Long tenantId,
                     @Param("updateBy") Long updateBy);

    /**
     * 检查用户名是否存在（支持多租户）
     * @param username 用户名
     * @param excludeUserId 排除的用户ID
     * @param tenantId 租户ID
     * @return 存在数量
     */
    @Select("SELECT COUNT(1) FROM sys_user WHERE username = #{username} AND id != #{excludeUserId} AND tenant_id = #{tenantId} AND deleted = 0")
    int checkUsernameExists(@Param("username") String username, 
                           @Param("excludeUserId") Long excludeUserId, 
                           @Param("tenantId") Long tenantId);

    /**
     * 检查邮箱是否存在（支持多租户）
     * @param email 邮箱
     * @param excludeUserId 排除的用户ID
     * @param tenantId 租户ID
     * @return 存在数量
     */
    @Select("SELECT COUNT(1) FROM sys_user WHERE email = #{email} AND id != #{excludeUserId} AND tenant_id = #{tenantId} AND deleted = 0")
    int checkEmailExists(@Param("email") String email, 
                        @Param("excludeUserId") Long excludeUserId, 
                        @Param("tenantId") Long tenantId);

    /**
     * 检查手机号是否存在（支持多租户）
     * @param phone 手机号
     * @param excludeUserId 排除的用户ID
     * @param tenantId 租户ID
     * @return 存在数量
     */
    @Select("SELECT COUNT(1) FROM sys_user WHERE phone = #{phone} AND id != #{excludeUserId} AND tenant_id = #{tenantId} AND deleted = 0")
    int checkPhoneExists(@Param("phone") String phone, 
                        @Param("excludeUserId") Long excludeUserId, 
                        @Param("tenantId") Long tenantId);

    /**
     * 根据租户ID查询用户列表
     * @param tenantId 租户ID
     * @return 用户列表
     */
    @Select("SELECT * FROM sys_user WHERE tenant_id = #{tenantId} AND deleted = 0 ORDER BY create_time DESC")
    List<User> selectUsersByTenantId(@Param("tenantId") Long tenantId);

    /**
     * 启用/禁用用户
     * @param userId 用户ID
     * @param status 用户状态
     * @param tenantId 租户ID
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    @Update("UPDATE sys_user SET status = #{status}, update_time = NOW(), update_by = #{updateBy} WHERE id = #{userId} AND tenant_id = #{tenantId}")
    int updateUserStatus(@Param("userId") Long userId, 
                        @Param("status") UserStatus status, 
                        @Param("tenantId") Long tenantId,
                        @Param("updateBy") Long updateBy);

    /**
     * 批量逻辑删除用户（支持多租户）
     * @param userIds 用户ID列表
     * @param tenantId 租户ID
     * @param updateBy 更新人ID
     * @return 影响行数
     */
    int batchUpdateDeleted(@Param("userIds") List<Long> userIds, 
                          @Param("tenantId") Long tenantId,
                          @Param("updateBy") Long updateBy);

    /**
     * 查询用户列表（支持多租户）
     * @param queryDTO 查询条件
     * @return 用户列表
     */
    List<UserListVO> selectUserList(@Param("query") UserQueryDTO queryDTO);
}